package com.atguigu.gmall.payment.controller;

import com.alipay.api.AlipayApiException;
import com.alipay.api.internal.util.AlipaySignature;
import com.atguigu.gmall.common.constant.MqConst;
import com.atguigu.gmall.common.result.Result;
import com.atguigu.gmall.common.service.RabbitService;
import com.atguigu.gmall.model.enums.PaymentType;
import com.atguigu.gmall.model.payment.PaymentInfo;
import com.atguigu.gmall.payment.config.AlipayConfig;
import com.atguigu.gmall.payment.service.AlipayService;
import com.atguigu.gmall.payment.service.PaymentInfoService;
import org.checkerframework.checker.units.qual.A;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.*;

import java.math.BigDecimal;
import java.util.Map;
import java.util.concurrent.TimeUnit;

/**
 * @program: gmall-parent
 * @author: Mr.Zhuo
 * @create: 2022-04-21 10:53
 **/
@Controller
@RequestMapping("/api/payment/alipay")
public class AlipayController {

    @Value("${app_id}")
    private String app_id;

    @Autowired
    private AlipayService alipayService;

    @Autowired
    private PaymentInfoService paymentInfoService;

    @Autowired
    private RedisTemplate redisTemplate;


    // 发起退款！http://localhost:8205/api/payment/alipay/refund/20
    @RequestMapping("refund/{orderId}")
    @ResponseBody
    public Result refund(@PathVariable(value = "orderId") Long orderId) {
        // 调用退款接口
        boolean flag = alipayService.refund(orderId);

        return Result.ok(flag);
    }


    @GetMapping("/callback/return")
    public String callback() {
        return "redirect:" + AlipayConfig.return_order_url;
    }

    @ResponseBody
    @GetMapping("submit/{orderId}")
    public String submit(@PathVariable Long orderId) throws AlipayApiException {

        String pay = alipayService.createaliPay(orderId);
        return pay;
    }

    /**
     * 根据outTradeNo来查询订单
     * @param outTradeNo
     * @return
     */
    @GetMapping("getPaymentInfo/{outTradeNo}")
    @ResponseBody
    public PaymentInfo getPaymentInfo(@PathVariable String outTradeNo){
        PaymentInfo paymentInfo = paymentInfoService.selectPaymentInfoBy(outTradeNo);
        if (null!=paymentInfo){
            return paymentInfo;
        }
        return null;
    }


    // 查看是否有交易记录
    @RequestMapping("checkPayment/{orderId}")
    @ResponseBody
    public Boolean checkPayment(@PathVariable Long orderId){
        // 调用退款接口
        boolean flag = alipayService.checkPayment(orderId);
        return flag;
    }

    // 根据订单Id关闭订单
    @GetMapping("closePay/{orderId}")
    @ResponseBody
    public Boolean closePay(@PathVariable Long orderId){
        Boolean aBoolean = alipayService.closePay(orderId);
        return aBoolean;
    }


    //https: //商家网站通知地址?voucher_detail_list=[{"amount":"0.20","merchantContribute":"0.00","name":"5折券","otherContribute":"0.20","type":"ALIPAY_DISCOUNT_VOUCHER","voucherId":"2016101200073002586200003BQ4"}]&fund_bill_list=[{"amount":"0.80","fundChannel":"ALIPAYACCOUNT"},{"amount":"0.20","fundChannel":"MDISCOUNT"}]&subject=PC网站支付交易&trade_no=2016101221001004580200203978&gmt_create=2016-10-12 21:36:12&notify_type=trade_status_sync&total_amount=1.00&out_trade_no=mobile_rdm862016-10-12213600&invoice_amount=0.80&seller_id=2088201909970555&notify_time=2016-10-12 21:41:23&trade_status=TRADE_SUCCESS&gmt_payment=2016-10-12 21:37:19&receipt_amount=0.80&passback_params=passback_params123&buyer_id=2088102114562585&app_id=2016092101248425&notify_id=7676a2e1e4e737cff30015c4b7b55e3kh6& sign_type=RSA2&buyer_pay_amount=0.80&sign=***&point_amount=0.00
    @PostMapping("/callback/notify")
    @ResponseBody
    public String callbackNotify(@RequestParam Map paramsMap) {
        System.out.println("你回来了.....");
        // Map<String, String> paramsMap = ... // 将异步通知中收到的所有参数都存放到map中
        boolean signVerified = false; //调用SDK验证签名
        try {
            signVerified = AlipaySignature.rsaCheckV1(paramsMap, AlipayConfig.alipay_public_key, AlipayConfig.charset, AlipayConfig.sign_type);
        } catch (AlipayApiException e) {
            e.printStackTrace();
        }
        if (signVerified) {
            // TODO 验签成功后，按照支付结果异步通知中的描述，对支付结果中的业务内容进行二次校验，校验成功后在response中返回success并继续商户自身业务处理，校验失败返回failure
            // out_trade_no
            String out_trade_no = (String) paramsMap.get("out_trade_no");
            PaymentInfo paymentInfo = paymentInfoService.selectPaymentInfoBy(out_trade_no);
            // total_amount
            String total_amount = (String) paramsMap.get("total_amount");
            // app_id
            String app_id = (String) paramsMap.get("app_id");
            // notify_id
            String notify_id = (String) paramsMap.get("notify_id");

            // 利用redis进行判断
            Boolean ifPresent = redisTemplate.opsForValue().setIfAbsent(notify_id, notify_id, 1462, TimeUnit.MINUTES);
            if (!ifPresent) {
                return "failure";
            }

            if (paymentInfo == null || new BigDecimal("0.01").compareTo(new BigDecimal(total_amount)) != 0 ||
                    !app_id.equals(app_id)) {
                return "failure";
            }

            if ("TRADE_SUCCESS".equals(paramsMap.get("trade_status")) || "TRADE_FINISHED".equals(paramsMap.get("trade_status"))) {
                // 进行修改paymentInfo的状态
                paymentInfoService.updatePaymentInfo(paymentInfo.getId(), paramsMap);
            }
            return "success";
        } else {
            // TODO 验签失败则记录异常日志，并在response中返回failure.
            return "failure";
        }
    }
}
